package com.adspert.commons.util;

import java.text.Format;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

public class DateUtils {

	public static final long ONE_DAY_INTERVAL = 1000 * 3600 * 24;

	public static final String YYYYMMDD = "yyyy-MM-dd";

	public static final String YYYYMMDDHHMISS = "yyyy-MM-dd HH:mm:ss";

	/**
	 * 比较StartDate和EndDate, startDate和endDate必须是凌晨的0:00:00:000.
	 */
	public static int dateDiff(Date startDate, Date endDate) {
		assert (startDate.getTime() % ONE_DAY_INTERVAL == 0 && endDate.getTime() % ONE_DAY_INTERVAL == 0);
		long interval = endDate.getTime() - startDate.getTime();
		return (int) (interval / ONE_DAY_INTERVAL);
	}

	/**
	 * 得到某天的DayOfWeek: 星期一为0...星期天为6;
	 */
	public static int getDayOfWeek(Date theDay) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(theDay);
		return (cal.get(Calendar.DAY_OF_WEEK) + 5) % 7;
	}

	public static String getMonthDayStr(Date date) {
		StringBuffer dateBuffer = new StringBuffer();
		int month = getMonth(date);
		if (month <= 9) {
			dateBuffer.append("0" + month);
		} else {
			dateBuffer.append(month);
		}
		int day = getDay(date);
		if (day <= 9) {
			dateBuffer.append("0" + day);
		} else {
			dateBuffer.append(day);
		}
		return dateBuffer.toString();
	}

	/**
	 * 日期按照指定格式转换为字符串
	 * 
	 * @param date
	 * @param formatStr
	 * @return
	 */
	public static String date2String(Date date, String formatStr, Locale locale) {
		try {
			Format format = new SimpleDateFormat(formatStr, locale);
			return format.format(date);
		} catch (Exception pe) {
			System.err.println(pe.getMessage());
		}
		return "";
	}

	public static String date2String(Date date, String formatStr) {
		return date2String(date, formatStr, Locale.getDefault());
	}

	/**
	 * 使用参数Format将字符串转为Date
	 * 
	 * @throws ParseException
	 */
	public static Date parse(String strDate, String pattern) {
		return parse(strDate, pattern, Locale.getDefault());
	}

	/**
	 * 使用参数Format将字符串转为Date
	 * 
	 * @throws ParseException
	 */
	public static Date parse(String strDate, String pattern, Locale locale) {
		Date date = null;
		try {
			date = new SimpleDateFormat(pattern, locale).parse(strDate);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return date;
	}

	public static Long getSeconds(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.getTimeInMillis() / 1000;
	}

	public static Long getMilliSeconds(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.getTimeInMillis();
	}

	/**
	 * 字符串转成日期，格式为yyyy-MM-dd
	 */
	public static Date getDate(String date) {
		return parse(date, YYYYMMDD);
	}

	/**
	 * 得到今天的日期时间，不需要/时/分/秒
	 */
	public static Date getCurDate() {
		Calendar c1 = Calendar.getInstance();
		GregorianCalendar gc = new GregorianCalendar(c1.get(Calendar.YEAR), c1.get(Calendar.MONTH), c1.get(Calendar.DAY_OF_MONTH));
		return gc.getTime();
	}

	/**
	 * 去掉/时/分/秒
	 */
	public static Date toDay(Date dt) {
		Calendar c = Calendar.getInstance();
		c.clear();
		c.setTime(dt);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		return c.getTime();
	}

	/**
	 * 得到今天的小时时间，不需要/分/秒
	 */
	public static Date getCurrentHH() {
		Calendar c1 = Calendar.getInstance();
		c1.setTime(new Date());
		Calendar c2 = Calendar.getInstance();
		c2.set(c1.get(Calendar.YEAR), c1.get(Calendar.MONTH), c1.get(Calendar.DAY_OF_MONTH), c1.get(Calendar.HOUR_OF_DAY), 0, 0);
		return c2.getTime();
	}

	/**
	 * 返回当前日期字符串
	 */
	public static String getToday() {
		Date today = new Date();
		return date2String(today, YYYYMMDD);
	}

	/**
	 * 得到增加i天后的时间，加（5）或减（-5）
	 */
	public static Date addDay(Date date, int i) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.DATE, i);
		return cal.getTime();
	}

	public static int getDay(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.DAY_OF_MONTH);
	}

	public static int getMonth(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.MONTH) + 1;
	}

	public static int getYear(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.YEAR);
	}

	/**
	 * MM/DD/YYYY, TODO:这两个函数其实没有必要，待删除
	 */
	public static String buildDateString(Date reportDate) {
		return date2String(reportDate, "MM/dd/yyyy");
	}

	/**
	 * YYYY-MM-DD TODO:这两个函数其实没有必要，待删除
	 */
	public static String getDateString(Date reportDate) {
		return date2String(reportDate, "yyyy-MM-dd");
	}

	public static java.sql.Date convertToSqlDate(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return new java.sql.Date(cal.getTimeInMillis());
	}

	public static int getDaysBetween(Date d1, Date d2) {
		if (d1.after(d2)) {
			Date swap = d1;
			d1 = d2;
			d2 = swap;
		}
		Calendar c1 = Calendar.getInstance();
		c1.setTime(d1);
		Calendar c2 = Calendar.getInstance();
		c2.setTime(d2);
		int days = c2.get(Calendar.DAY_OF_YEAR) - c1.get(Calendar.DAY_OF_YEAR);
		int y2 = c2.get(Calendar.YEAR);
		if (c1.get(Calendar.YEAR) != y2) {
			c1 = (Calendar) c1.clone();
			do {
				days += c1.getActualMaximum(Calendar.DAY_OF_YEAR);
				c1.add(Calendar.YEAR, 1);
			} while (c1.get(Calendar.YEAR) != y2);
		}
		return days;
	}

	/**
	 * author saya 传一个日期获得当月的第一天和最后一天
	 */
	public static Date[] getMonthArea(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DATE, 1);
		Date[] monthArea = new Date[2];
		monthArea[0] = cal.getTime();
		cal.add(Calendar.MONTH, 1);
		cal.add(Calendar.DATE, -1);
		monthArea[1] = cal.getTime();
		return monthArea;
	}

	@SuppressWarnings("deprecation")
	public static String getGMTDate(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		String dateStr = date.toGMTString();
		dateStr = dateStr.substring(0, dateStr.length() - 12);
		return dateStr;
	}

	/**
	 * author saya 传一个日期小时
	 */
	public static int getHour(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.HOUR_OF_DAY);
	}

	/**
	 * author saya 传一个日期小时
	 */
	public static int getMinite(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.MINUTE);
	}

	/**
	 * author saya 传一个日期小时
	 */
	public static int getSecond(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.SECOND);
	}

	/**
	 * @param startDate
	 *            2007-8-27
	 * @param endDate
	 *            2007-8-28
	 * @return 27 Aug - 28 Aug 2007 (2days)
	 */
	public static String getDateRangeValue(Date startDate, Date endDate) {
		if (!isDateTime(startDate)) {
			startDate = addDay(startDate, 1);
		}
		if (!isDateTime(endDate)) {
			endDate = addDay(endDate, 1);
		}
		String startDateStr = getGMTDate(startDate);
		String endDateStr = getGMTDate(endDate);
		Calendar startCalendar = Calendar.getInstance();
		startCalendar.setTime(startDate);
		Calendar endCalendar = Calendar.getInstance();
		endCalendar.setTime(endDate);
		if (startCalendar.get(Calendar.YEAR) == endCalendar.get(Calendar.YEAR)) {
			startDateStr = startDateStr.replaceAll(String.valueOf(startCalendar.get(Calendar.YEAR)), "").trim();
		}
		int days = getDaysBetween(startDate, endDate) + 1; // 注意包含起始日期
		return startDateStr + " - " + endDateStr + "(" + days + " days)";
	}

	private static boolean isDateTime(Date date) {
		if (getHour(date) == 0 && getMinite(date) == 0 && getSecond(date) == 0) {
			return false;
		}
		return true;
	}

	public static Integer getWeekOfYear(Date date) {
		Calendar cld = Calendar.getInstance();
		cld.setTime(date);
		return cld.get(Calendar.WEEK_OF_YEAR);
	}

	/**
	 * 
	 * Jensen 2008-12-11 下午06:28:56 获取以本月为起点的任一月的最初时间点
	 */
	public static Date getBeginOfMonth(int n) {
		Calendar c = Calendar.getInstance();
		c.set(Calendar.DAY_OF_MONTH, 1);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		c.set(Calendar.MILLISECOND, 0);
		c.add(Calendar.MONTH, n);
		return c.getTime();
	}

	/**
	 * 
	 * Jensen 2008-12-11 下午06:37:28 获取以本月为起点的任一月的最末时间点
	 */
	public static Date getEndOfMonth(int n) {
		Calendar c = Calendar.getInstance();
		c.set(Calendar.DAY_OF_MONTH, 1);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		c.set(Calendar.MILLISECOND, 0);
		c.add(Calendar.MONTH, n + 1);
		c.setTimeInMillis(c.getTimeInMillis() - 1);
		return c.getTime();
	}

	/**
	 * 获取本月的最初时间点 Jensen 2008-12-11 下午06:44:42
	 * 
	 */
	public static Date getBeiginThisMonth() {
		return getBeginOfMonth(0);
	}

	/**
	 * 获取本月最末时间点 Jensen 2008-12-11 下午06:46:10
	 * 
	 */
	public static Date getEndThisMonth() {
		return getEndOfMonth(0);
	}

	public static void main(String args[]) {
		Calendar c  = Calendar.getInstance();
		c.setTime(DateUtils.getDate("2009-12-31"));
		c.add(Calendar.DAY_OF_WEEK, -456);
		System.out.println(DateUtils.getDateString(c.getTime()));
		// Date d = DateUtils.getDate("2008-08-01");
		// if(d.equals(DateUtils.parse("Aug 1, 2008", "MMM dd, yyyy",
		// Locale.ENGLISH))){
		// System.out.println("OK");
		// }else{
		// System.out.println("No");
		// }
		// System.out.println(DateUtils.getEndThisMonth());

	}
}
